/**
 * Created with IntelliJ IDEA.
 * User: ajhin
 * Date: 3/22/14
 * Time: 6:59 PM
 * To change this template use File | Settings | File Templates.
 */
package com.societyGames.codeAlong.state.codeExercise.model.testCase
{
import com.societyGames.codeAlong.state.codeExercise.model.Exception;
import com.societyGames.codeAlong.state.codeExercise.model.ExceptionEvent;
import com.societyGames.codeAlong.state.codeExercise.model.TestCaseStatus;

import flash.events.Event;

public class ExecuteState extends TestCaseControllerState implements IStoppable
{
  public function ExecuteState(testCaseController:TestCaseController)
  {
    super(testCaseController);
  }

  override public function enter():void
  {
    var testCase:TestCase = _testCaseController.selectedTestCase;
    prepareTestCaseForExecute(testCase);
    testCase.execute(_testCaseController._executeByteArray);
  }

  public function stop():void
  {
    var testCase:TestCase = _testCaseController.selectedTestCase;
    testCase.stop();
  }

  private function prepareTestCaseForExecute(testCase:TestCase):void
  {
    testCase.outputEventObject.addEventListener(_testCaseController._testCaseOutputHandler);
    testCase.testCaseStatusChangedEventObject.addEventListener(testCaseStatusChangedHandler);
  }

  private function cleanUpTestCaseFromExecute(testCase:TestCase):void
  {
    testCase.outputEventObject.removeEventListener(_testCaseController._testCaseOutputHandler);
    testCase.testCaseStatusChangedEventObject.removeEventListener(testCaseStatusChangedHandler);
  }

  internal function testCaseStatusChangedHandler(event:Event):void
  {
    _testCaseController._selectedCaseStatusChangedEventObject.dispatchEvent();

    var testCase:TestCase = TestCase(event.target);
    switch (testCase.testCaseStatus)
    {
      case TestCaseStatus.stopped:
        cleanUpTestCaseFromExecute(testCase);
        _testCaseController._executeByteArray = null;
        _testCaseController._stateMachine.gotoState(_testCaseController._failState);
        break;
      case TestCaseStatus.exceptioned:
        cleanUpTestCaseFromExecute(testCase);
        _testCaseController._executeByteArray = null;

        //Let everyone else know.
        var error:Error = testCase.error;
        _testCaseController._exceptionEventObject.dispatchEvent(new ExceptionEvent(_testCaseController._exceptionEventObject.type, Exception.fromError(error)));

        _testCaseController._stateMachine.gotoState(_testCaseController._exceptionState);
        break;
      case TestCaseStatus.unhandledExceptioned:
        cleanUpTestCaseFromExecute(testCase);
        _testCaseController._executeByteArray = null;

        //Let everyone else know.
        _testCaseController._unhandledExceptionEventObject.dispatchEvent(new Event(_testCaseController._unhandledExceptionEventObject.type));

        _testCaseController._stateMachine.gotoState(_testCaseController._exceptionState);
        break;
      case TestCaseStatus.failed:
        cleanUpTestCaseFromExecute(testCase);
        _testCaseController._executeByteArray = null;
        _testCaseController._stateMachine.gotoState(_testCaseController._failState);
        break;
      case TestCaseStatus.succeeded:
        cleanUpTestCaseFromExecute(testCase);
        //This case is success.
        _testCaseController._successCount++;

        if (_testCaseController._successCount == _testCaseController._testCases.length)
        {
          _testCaseController._stateMachine.gotoState(_testCaseController._successState);
        }
        else //Move to next case
        {
          _testCaseController._stateMachine.gotoState(_testCaseController._delayState);
        }
        break;
    }
  }

}
}
